package cz.data.domain.market.mapping.handler.interceptor;

import com.alibaba.fastjson.JSONObject;
import cz.data.common.base.BaseResponse;
import cz.data.common.base.SimpleDataResponse;
import cz.data.common.base.TableDataResponse;
import cz.data.common.core.AuthUser;
import cz.data.common.core.DataConstant;
import cz.data.common.utils.IPUtil;
import cz.data.common.utils.JsonCommon;
import cz.data.common.utils.SecurityUtil;
import cz.data.common.utils.SpringContextHolder;
import cz.data.domain.market.mapping.listener.event.ApiAccessLogEvent;
import cz.data.domain.market.model.dto.ApiLogDto;
import cz.data.domain.market.model.dto.TableApiSettings;
import cz.data.domain.market.model.entity.TableApiEntity;
import cz.data.platform.web.utils.SignUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.Objects;

@Component
public class TableApiRequestInterceptor extends AbstractRequestInterceptor {

    public boolean signValidate(HttpServletRequest request,
                                TableApiEntity tableApi,
                                Map<String, Object> requestParams,
                                Map<String, Object> requestHeaders,
                                Map<String, Object> requestBodys) {
        TableApiSettings settings = tableApi.getSettings();
        if (Boolean.TRUE.equals(settings.getVerSign())) {
            Objects.requireNonNull(requestHeaders, "请求验签缺少请求头参数");
            AuthUser authUser = SecurityUtil.requireAuthUser();
            String appSecret = authUser.getAppSecret();
            String method = request.getMethod();
            String uri = request.getRequestURI();
            Object requestSignature = requestHeaders.remove(SignUtils.X_CA_SIGNATURE);
            if (Objects.isNull(requestSignature) || StringUtils.isBlank(appSecret))
                return false;
            JSONObject headers = new JSONObject(requestHeaders);
            String sign = SignUtils.sign(appSecret, method, uri, headers, null, null);
            return StringUtils.equals(requestSignature.toString(), sign);
        } else {
            return true;
        }
    }

    public void postLogHandle(long startTimeMillis, HttpServletRequest request,
                              TableApiEntity tableApi, JSONObject params,
                              Exception e, BaseResponse response) {
        ApiLogDto apiLog = new ApiLogDto();
        apiLog.setApiId(tableApi.getId());
        apiLog.setCallerIp(IPUtil.getIpAddr(request));
        apiLog.setCallerUrl(request.getRequestURI());
        apiLog.setCallerDate(LocalDateTime.now());
        if (Objects.isNull(e)) {
            if (response instanceof TableDataResponse) {
                TableDataResponse<?> dataResponse = (TableDataResponse<?>) response;
                apiLog.setCallerSize(dataResponse.getData().size());
            } else if (response instanceof SimpleDataResponse) {
                apiLog.setCallerSize(1);
            } else {
                apiLog.setCallerSize(0);
            }
            apiLog.setStatus(DataConstant.EnableState.ENABLE.getKey());
        } else {
            apiLog.setStatus(DataConstant.EnableState.DISABLE.getKey());
            apiLog.setMsg(e.getMessage());
        }
        apiLog.setCallerParams(JsonCommon.toJson(params));
        apiLog.setTime(System.currentTimeMillis() - startTimeMillis);
        String userId = SecurityUtil.getUserId();
        if (StringUtils.isNotBlank(userId)) {
            apiLog.setCallerId(userId);
        }
        SpringContextHolder.publishEvent(new ApiAccessLogEvent(apiLog));
    }
}
